function ReloadPistolDone takes nothing returns nothing
	local timer reloadTimer = GetExpiredTimer()
	local integer timerId = GetHandleId(reloadTimer)
	local unit gunner = LoadUnitHandle(udg_HT , timerId , 3 )
	local item gun = LoadItemHandle(udg_HT , timerId , 4 )
	local item bullet = LoadItemHandle(udg_HT , timerId , 5 )
	//--
	call PauseTimer(reloadTimer)
	call FlushChildHashtable(udg_HT , timerId)
	call DestroyTimer(reloadTimer)
	if gun != null and bullet != null and UnitHasItem( gunner , gun ) and UnitHasItem( gunner , bullet ) then
		call SetItemCharges( gun , 7 )
		call SetItemCharges( bullet , GetItemCharges( bullet ) - 7 )
		if GetItemCharges( bullet ) <= 0 then
			call RemoveItem( bullet )
		endif
		call PlaySoundOnUnit( gunner , "clipin.wav" )
	endif
	call SetItemDroppable( gun , true )
	call SetItemDroppable( bullet , true )
	call SaveBoolean( udg_UnitDataHashTable , GetHandleId( gunner ) , StringHash("RELOADING") , false )
	//--
	set gun = null
	set bullet = null
	set gunner = null
	set reloadTimer = null
endfunction

function ReloadPistol takes unit gunner returns nothing
	local item gun = GetItemOfTypeFromUnitBJ( gunner , 'I004' )
	local item bullet  = GetItemOfTypeFromUnitBJ( gunner , 'I005' )
	local player gunnerOwner = GetOwningPlayer( gunner )
	local boolean reloading = LoadBoolean( udg_UnitDataHashTable , GetHandleId( gunner ) , StringHash("RELOADING") )
	local timer reloadTimer = null
	local integer timerId = 0
	//--
	if gun != null and bullet != null and not reloading and GetItemCharges( gun ) < 7 then
		call SetItemDroppable( gun , false )
		call SetItemDroppable( bullet , false )	
		call SaveBoolean( udg_UnitDataHashTable , GetHandleId( gunner ) , StringHash("RELOADING") , true )
		call SetItemCharges( gun , 0 )
		set reloadTimer = CreateTimer(  )
		set timerId = GetHandleId(reloadTimer)
		call SaveUnitHandle( udg_HT , timerId , 3 , gunner )
		call SaveItemHandle( udg_HT , timerId , 4 , gun )
		call SaveItemHandle( udg_HT , timerId , 5 , bullet )
		call TimerStart( reloadTimer , 3.0 , false , function ReloadPistolDone )
		call DisplayTimedTextToPlayer( gunnerOwner , 0 , 0 , 2.0 , "更換彈夾中...." )
		call PlaySoundOnUnit( gunner , "clipout.wav" )
	endif
	//--
	set gun = null
	set bullet = null
	set gunnerOwner = null
	set reloadTimer = null
endfunction

function BulletDamage takes nothing returns nothing
	local unit target = GetEnumUnit()
	//--
	if IsUnitEnemy(target , udg_TempPlayer) and IsUnitInRangeLoc(target , udg_TempLocation , udg_TempRadius) and not IsUnitType(target , UNIT_TYPE_STRUCTURE) and GetUnitState(target , UNIT_STATE_LIFE) > 0.0 then
		call UnitDamageTarget(udg_TempDamager , target , udg_TempDamage , true , false , ATTACK_TYPE_NORMAL, DAMAGE_TYPE_COLD , WEAPON_TYPE_METAL_MEDIUM_BASH)
		set udg_TempBoolean = true
	endif
	//--
	set target = null
endfunction

function BulletRoutine takes nothing returns nothing
	local timer bulletTimer = GetExpiredTimer(  )
	local integer timerId = GetHandleId( bulletTimer )
	local unit bulletEffect = LoadUnitHandle(udg_HT , timerId , 3 )
	local real dx = LoadReal( udg_HT , timerId , 4 )
	local real dy = LoadReal( udg_HT , timerId , 5 )
	local real process = LoadReal( udg_HT , timerId , 6 )
	local boolean end = false
	//--
	//造成傷害
	set udg_TempDamager = bulletEffect
	set udg_TempPlayer = GetOwningPlayer(bulletEffect)
	set udg_TempDamage = 200.0
	set udg_TempRadius = 50.0
	set udg_TempLocation = GetUnitLoc(bulletEffect)
	set udg_TempBoolean = false
	set bj_wantDestroyGroup = true
	call ForGroupBJ(GetUnitsInRangeOfLocMatching(udg_TempRadius+70.0, udg_TempLocation , null) , function BulletDamage)
	call RemoveLocation(udg_TempLocation)
	//移動子彈
	if not udg_TempBoolean and process < 40.0 then
		set process = process + 1.0
		call SaveReal( udg_HT , timerId , 6 , process )
		call SetUnitX( bulletEffect , GetUnitX( bulletEffect ) + dx )
		call SetUnitY( bulletEffect , GetUnitY( bulletEffect ) + dy )
	else
		set end = true
	endif
	if end then
		call PauseTimer( bulletTimer )
		call FlushChildHashtable( udg_HT , timerId )
		call DestroyTimer( bulletTimer )
		call KillUnit( bulletEffect )
		call RemoveUnit( bulletEffect )
	endif
	//--
	set bulletTimer = null
	set bulletEffect = null
endfunction

function Trig_Shot_Effect takes nothing returns nothing
	local unit gunner = GetTriggerUnit(  )
	local player gunnerOwner = GetOwningPlayer( gunner )
	local location gunnerLocation = GetUnitLoc( gunner )
	local location targetLocation = GetSpellTargetLoc(  )
	local item gun = GetItemOfTypeFromUnitBJ( gunner , 'I004' )
	local real angle = AngleBetweenPoints( gunnerLocation , targetLocation )
	local real delta = 2500.0 * 0.01 // speed setting
	local real dx = Cos( angle * bj_DEGTORAD ) * delta
	local real dy = Sin( angle * bj_DEGTORAD ) * delta
	local unit bulletEffect = CreateUnit( gunnerOwner , 'e003' , GetLocationX( gunnerLocation ) , GetLocationY( gunnerLocation ) , angle )
	local timer bulletTimer = CreateTimer(  )
	local integer timerId = GetHandleId( bulletTimer )
	//--
	call SetUnitX( bulletEffect , GetLocationX( gunnerLocation ) + dx )
	call SetUnitY( bulletEffect , GetLocationY( gunnerLocation ) + dy )
	call SetItemCharges( gun , GetItemCharges( gun ) - 1 )
	call SaveUnitHandle( udg_HT , timerId , 3 , bulletEffect )
	call SaveReal( udg_HT , timerId , 4 , dx )
	call SaveReal( udg_HT , timerId , 5 , dy )
	call SaveReal( udg_HT , timerId , 6 , 0.0 )
	call TimerStart( bulletTimer , 0.01 , true , function BulletRoutine )
	if GetItemCharges( gun ) < 1 then
		call ReloadPistol(gunner)
	endif
	//聲音
	call PlaySoundOnUnit( gunner , "Units\\Human\\Rifleman\\RiflemanAttack1.wav" )
	call SetUnitAnimationByIndex( gunner , 171 )
	//--
	set gunner = null
	set gunnerOwner = null
	call RemoveLocation( gunnerLocation )
	set gunnerLocation = null
	call RemoveLocation( targetLocation )
	set targetLocation = null
	set gun = null
	set bulletEffect = null
	set bulletTimer = null
endfunction

function Trig_Shot_Actions takes nothing returns nothing
	local unit gunner = GetTriggerUnit(  )
	local integer gunnerId = GetHandleId( gunner )
	local player gunnerOwner = GetOwningPlayer( gunner )
	local item gun = GetItemOfTypeFromUnitBJ( gunner , 'I004' )
	local integer gunCharge = GetItemCharges( gun )
	local item bullet = GetItemOfTypeFromUnitBJ( gunner , 'I005' )
	local boolean reloading = LoadBoolean( udg_UnitDataHashTable , gunnerId , StringHash("RELOADING") )
	//--	
	if gunCharge <= 0 or reloading or gun == null then
		call IssueImmediateOrder( gunner , "stop" )
	else
		return
	endif	
	if gun == null then
		call UnitRemoveAbility( gunner , 'A00O' )
	elseif reloading then
		call DisplayTimedTextToPlayer( gunnerOwner, 0 , 0 , 1.0 , "更換彈夾中" )
	elseif gunCharge <= 0 then
		if bullet == null then
			call DisplayTimedTextToPlayer( gunnerOwner, 0 , 0 , 2.0 , "沒彈藥了" )
		else
			call ReloadPistol( gunner )
		endif
	endif
endfunction

function Trig_Shot_Conditions takes nothing returns boolean
	return GetSpellAbilityId(  ) == 'A00O'
endfunction

function InitTrig_Shot takes nothing returns nothing
	local trigger shotEffectTrigger = CreateTrigger(  )
	//--
	set gg_trg_Shot = CreateTrigger(  )
	call TriggerRegisterAnyUnitEventBJ( gg_trg_Shot, EVENT_PLAYER_UNIT_SPELL_CHANNEL )
	call TriggerAddCondition( gg_trg_Shot, Condition( function Trig_Shot_Conditions ) )
	call TriggerAddAction( gg_trg_Shot, function Trig_Shot_Actions )
	
	call TriggerRegisterAnyUnitEventBJ( shotEffectTrigger, EVENT_PLAYER_UNIT_SPELL_EFFECT )
	call TriggerAddCondition( shotEffectTrigger, Condition( function Trig_Shot_Conditions ) )
	call TriggerAddAction( shotEffectTrigger, function Trig_Shot_Effect )
endfunction